package com.hospital.config.help;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hospital.service.publics.entity.PubUserInfo;
import com.hospital.service.publics.entity.help.PubUserInfoHelp;
import com.hospital.service.publics.service.PubUserInfoService;
import com.hospital.service.system.entity.SysConfiguration;
import com.hospital.service.system.entity.help.SysConfigurationHelp;
import com.hospital.service.system.service.SysConfigurationService;
import com.hospital.service.target.entity.*;
import com.hospital.service.target.entity.help.*;
import com.hospital.service.target.service.*;
import common.core.constant.Constant;
import common.core.util.CommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import enhance.plus.logic.LogicBaseEntity;
import enhance.redis.util.RedisUtil;

import java.util.List;
import java.util.Set;

/**
 * @author liubo
 * @created 2020-07-29 9:44
 */
@Slf4j
@Component
@EnableScheduling
public class DataCollectionHelper {

    /**
     * 定时任务刷新时间
     */
    private static final long SCHEDULED_TIME_MILLISECOND = 3600000L;


    /**
     * redis并发处理key 存在时间
     */
    private static final long REDIS_ABSENT_KEY_TIME = SCHEDULED_TIME_MILLISECOND / 1000 - 10;

    /**
     * redis默认缓存数据保存时间
     */
    private static final long REDIS_DEFAULT_SAVE_TIME = REDIS_ABSENT_KEY_TIME + 100;

    private PubUserInfoService pubUserInfoService;
    private SysConfigurationService sysConfigurationService;
    private TarReagentInfoService tarReagentInfoService;
    private TarProteinNucleicAcidInfoService tarProteinNucleicAcidInfoService;
    private TarSpecialDyeingBaseService tarSpecialDyeingBaseService;
    private TarConventionalDyeingInfoService tarConventionalDyeingInfoService;
    private RedisUtil redisUtil;
    private Set<? extends LogicBaseEntity> logicBaseEntitys;
    private String serviceName;

    @Autowired
    public DataCollectionHelper(
            RedisUtil redisUtil,
            Set<? extends LogicBaseEntity> logicBaseEntitys,
            @Value("${spring.application.name}") String serviceName,
            PubUserInfoService pubUserInfoService,
            SysConfigurationService sysConfigurationService,
            TarReagentInfoService tarReagentInfoService,
            TarProteinNucleicAcidInfoService tarProteinNucleicAcidInfoService,
            TarSpecialDyeingBaseService tarSpecialDyeingBaseService,
            TarConventionalDyeingInfoService tarConventionalDyeingInfoService
    ) {
        this.redisUtil = redisUtil;
        this.logicBaseEntitys = logicBaseEntitys;
        this.serviceName = serviceName;
        this.pubUserInfoService = pubUserInfoService;
        this.sysConfigurationService = sysConfigurationService;
        this.tarReagentInfoService = tarReagentInfoService;
        this.tarProteinNucleicAcidInfoService = tarProteinNucleicAcidInfoService;
        this.tarSpecialDyeingBaseService = tarSpecialDyeingBaseService;
        this.tarConventionalDyeingInfoService = tarConventionalDyeingInfoService;
    }

    /**
     * 用户信息收集
     */
    @Scheduled(fixedRate = SCHEDULED_TIME_MILLISECOND)
    public void refreshUserInfo() {
        String key = CommonUtil.join(":", Constant.REDIS_ITEM_GENERATE_KEY, PubUserInfo.class.getSimpleName(),
                CommonUtil.dbForDBToFistLowercaseHump(PubUserInfoHelp.userNumber));

        String absentKey = CommonUtil.join(":", key, "absent");
        if (RedisUtil.setIfAbsent(absentKey, key, REDIS_ABSENT_KEY_TIME)) {
            log.debug("{} 服务 设备类别数据收集", serviceName);
            List<PubUserInfo> pubUserInfoList = this.pubUserInfoService.list();
                if (CommonUtil.isNotEmpty(pubUserInfoList)) {
                RedisUtil.del(key);
                for (PubUserInfo pubUserInfo : pubUserInfoList) {
                    RedisUtil.hset(key, pubUserInfo.getUserNumber(), pubUserInfo.getUserName(), REDIS_DEFAULT_SAVE_TIME);
                }
            }
        }
    }

    /**
     * 试剂表信息收集
     */
    @Scheduled(fixedRate = SCHEDULED_TIME_MILLISECOND)
    public void refreshReagentInfo() {
        String key = CommonUtil.join(":", Constant.REDIS_ITEM_GENERATE_KEY, TarReagentInfo.class.getSimpleName(),
                CommonUtil.dbForDBToFistLowercaseHump(TarReagentInfoHelp.reagentNumber));

        String absentKey = CommonUtil.join(":", key, "absent");
        if (RedisUtil.setIfAbsent(absentKey, key, REDIS_ABSENT_KEY_TIME)) {
            log.debug("{} 服务 设备类别数据收集", serviceName);
            List<TarReagentInfo> tarReagentInfoList = this.tarReagentInfoService.list();
            if (CommonUtil.isNotEmpty(tarReagentInfoList)) {
                RedisUtil.del(key);
                for (TarReagentInfo tarReagentInfo : tarReagentInfoList) {
                    RedisUtil.hset(key, tarReagentInfo.getReagentNumber(), tarReagentInfo.getReagentName(), REDIS_DEFAULT_SAVE_TIME);
                }
            }
        }
    }


    /**
     * 蛋白核酸表信息收集
     */
    @Scheduled(fixedRate = SCHEDULED_TIME_MILLISECOND)
    public void refreshProteinAcidInfo() {
        String key = CommonUtil.join(":", Constant.REDIS_ITEM_GENERATE_KEY, TarProteinNucleicAcidInfo.class.getSimpleName(),
                CommonUtil.dbForDBToFistLowercaseHump(TarProteinNucleicAcidInfoHelp.proteinNucleicAcidNumber));

        String absentKey = CommonUtil.join(":", key, "absent");
        if (RedisUtil.setIfAbsent(absentKey, key, REDIS_ABSENT_KEY_TIME)) {
            log.debug("{} 收集蛋白信息", serviceName);
            QueryWrapper<TarProteinNucleicAcidInfo> query1 = TarProteinNucleicAcidInfoHelp.createQuery();
            query1.eq(TarProteinNucleicAcidInfoHelp.isProtein, TarProteinNucleicAcidInfoHelp.isProtein_danbai);
            List<TarProteinNucleicAcidInfo> tarProteinNucleicAcidInfos1 = this.tarProteinNucleicAcidInfoService.list(query1);
            if (CommonUtil.isNotEmpty(tarProteinNucleicAcidInfos1)) {
                RedisUtil.del(key + TarProteinNucleicAcidInfoHelp.isProtein_danbai);
                for (TarProteinNucleicAcidInfo tarProteinNucleicAcidInfo : tarProteinNucleicAcidInfos1) {
                    log.debug("存储蛋白信息");
                    RedisUtil.hset(key + TarProteinNucleicAcidInfoHelp.isProtein_danbai, tarProteinNucleicAcidInfo.getProteinNucleicAcidNumber(), tarProteinNucleicAcidInfo.getName(), REDIS_DEFAULT_SAVE_TIME);
                }
            }

            log.debug("{} 收集核酸信息", serviceName);
            QueryWrapper<TarProteinNucleicAcidInfo> query2 = TarProteinNucleicAcidInfoHelp.createQuery();
            query2.eq(TarProteinNucleicAcidInfoHelp.isProtein, TarProteinNucleicAcidInfoHelp.isProtein_hesuan);
            List<TarProteinNucleicAcidInfo> tarProteinNucleicAcidInfos2 = this.tarProteinNucleicAcidInfoService.list(query2);
            if (CommonUtil.isNotEmpty(tarProteinNucleicAcidInfos1)) {
                RedisUtil.del(key + TarProteinNucleicAcidInfoHelp.isProtein_hesuan);
                for (TarProteinNucleicAcidInfo tarProteinNucleicAcidInfo : tarProteinNucleicAcidInfos2) {
                    log.debug("存储核酸信息");
                    RedisUtil.hset(key + TarProteinNucleicAcidInfoHelp.isProtein_hesuan, tarProteinNucleicAcidInfo.getProteinNucleicAcidNumber(), tarProteinNucleicAcidInfo.getName(), REDIS_DEFAULT_SAVE_TIME);
                }
            }
        }
    }

    /**
     * 特殊染色表信息收集
     */
    @Scheduled(fixedRate = SCHEDULED_TIME_MILLISECOND)
    public void refreshSpecialInfo() {
        String key = CommonUtil.join(":", Constant.REDIS_ITEM_GENERATE_KEY, TarSpecialDyeingBase.class.getSimpleName(),
                CommonUtil.dbForDBToFistLowercaseHump(TarSpecialDyeingBaseHelp.etsNumber));

        String absentKey = CommonUtil.join(":", key, "absent");
        if (RedisUtil.setIfAbsent(absentKey, key, REDIS_ABSENT_KEY_TIME)) {
            log.debug("{} 服务 设备类别数据收集", serviceName);
            List<TarSpecialDyeingBase> tarSpecialDyeingBaseList = this.tarSpecialDyeingBaseService.list();
            if (CommonUtil.isNotEmpty(tarSpecialDyeingBaseList)) {
                RedisUtil.del(key);
                for (TarSpecialDyeingBase tarSpecialDyeingBase : tarSpecialDyeingBaseList) {
                    RedisUtil.hset(key, tarSpecialDyeingBase.getEtsNumber(), tarSpecialDyeingBase.getName(), REDIS_DEFAULT_SAVE_TIME);
                }
            }
        }
    }

    /**
     * 常规h&E信息收集
     */
    @Scheduled(fixedRate = SCHEDULED_TIME_MILLISECOND)
    public void refreshDyeingInfo() {
        String key = CommonUtil.join(":", Constant.REDIS_ITEM_GENERATE_KEY, TarConventionalDyeingInfo.class.getSimpleName(),
                CommonUtil.dbForDBToFistLowercaseHump(TarConventionalDyeingInfoHelp.conventionalDyeingNumber));

        String absentKey = CommonUtil.join(":", key, "absent");
        if (RedisUtil.setIfAbsent(absentKey, key, REDIS_ABSENT_KEY_TIME)) {
            log.debug("{} 服务 设备类别数据收集", serviceName);
            List<TarConventionalDyeingInfo> list = this.tarConventionalDyeingInfoService.list();
            if (CommonUtil.isNotEmpty(list)) {
                RedisUtil.del(key);
                for (TarConventionalDyeingInfo tarConventionalDyeingInfo : list) {
                    RedisUtil.hset(key, tarConventionalDyeingInfo.getConventionalDyeingNumber(), tarConventionalDyeingInfo.getSearchName(), REDIS_DEFAULT_SAVE_TIME);
                }
            }
        }
    }

    /**
     * 系统配置信息收集
     */
    @Scheduled(fixedRate = SCHEDULED_TIME_MILLISECOND)
    public void refreshSystemConfigurationInfo() {
        String key = CommonUtil.join(":", Constant.REDIS_ITEM_GENERATE_KEY, SysConfiguration.class.getSimpleName(),
                CommonUtil.dbForDBToFistLowercaseHump(SysConfigurationHelp.id));
        String absentKey = CommonUtil.join(":", key, "absent");
        if (RedisUtil.setIfAbsent(absentKey, key, REDIS_ABSENT_KEY_TIME)) {
            log.debug("{} => 系统配置信息收集", serviceName);
            List<SysConfiguration> sysConfigurationList = this.sysConfigurationService.list();
            if (CommonUtil.isNotEmpty(sysConfigurationList)) {
                RedisUtil.del(key);
                for (SysConfiguration sysConfiguration : sysConfigurationList) {
                    RedisUtil.hset(key, sysConfiguration.getId(), sysConfiguration.getSysValue(), REDIS_DEFAULT_SAVE_TIME);
                }
            }
        }
    }
}
